
package com.hlkj.pay.app.pay.impl;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.collection.CollectionUtils;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.pay.app.pay.IPayChannelAppService;
import com.hlkj.pay.common.CommonResultCode;
import com.hlkj.pay.common.PayResultCode;
import com.hlkj.pay.enums.CommonEnum;
import com.hlkj.pay.enums.PayEnums;
import com.hlkj.pay.infrastructure.model.pay.PayChannelDO;
import com.hlkj.pay.service.common.IBusinessLogService;
import com.hlkj.pay.service.pay.IPayChannelService;
import com.hlkj.pay.vo.merchant.req.UpdateStatusReq;
import com.hlkj.pay.vo.pay.req.PayChannelReq;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.core.utils.BeanUtil;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

/**
 * @author HlpayTeam
 * @date 2024/09/23 11:36
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class PayChannelAppServiceImpl implements IPayChannelAppService {

    private final IPayChannelService payChannelService;

    private final IBusinessLogService businessChangeLogService;

    @Override
    public CommonResult<Void> savePayChannel(PayChannelReq payChannelReq) {
        log.info("savePayChannel payChannelReq:{}", JsonUtils.toJsonString(payChannelReq));
        try {
            PayChannelDO payChannelDO = payChannelService.queryByCode(payChannelReq.getCode());
            if (payChannelDO != null) {
                return CommonResult.error(PayResultCode.PAY_CHANNEL_EXITS);
            }
            // 去掉名称校验
            // payChannelDO = payChannelService.queryByName(payChannelReq.getName());
            // if (payChannelDO != null) {
            //     return CommonResult.error(PayResultCode.PAY_CHANNEL_EXITS);
            // }
            if (StringUtils.hasText(payChannelReq.getChannelConfig())) {
                try {
                    JsonUtils.parseArray(payChannelReq.getChannelConfig(), Object.class);
                }
                catch (Exception e) {
                    return CommonResult.error(CommonResultCode.PARAMETER_ERROR);
                }
            }
            if (StringUtils.hasText(payChannelReq.getMerchantConfig())) {
                try {
                    JsonUtils.parseArray(payChannelReq.getMerchantConfig(), Object.class);
                }
                catch (Exception e) {
                    return CommonResult.error(CommonResultCode.PARAMETER_ERROR);
                }
            }
            if (StringUtils.hasText(payChannelReq.getSpecialMerchantConfig())) {
                try {
                    JsonUtils.parseArray(payChannelReq.getSpecialMerchantConfig(), Object.class);
                }
                catch (Exception e) {
                    return CommonResult.error(CommonResultCode.PARAMETER_ERROR);
                }
            }

            payChannelDO = BeanUtil.copy(payChannelReq, PayChannelDO.class);
            if (!CollectionUtils.isEmpty(payChannelReq.getPayWapCodeList())) {
                payChannelDO.setPayCodes(JsonUtils.toJsonString(payChannelReq.getPayWapCodeList()));
            }
            payChannelService.save(payChannelDO);
            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("savePayChannel fail payChannelReq:{},message:{}", JsonUtils.toJsonString(payChannelReq), e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<Void> updatePayChannel(PayChannelReq payChannelReq) {
        log.info("updatePayChannel payChannelReq:{}", JsonUtils.toJsonString(payChannelReq));
        try {
            PayChannelDO payChannelDb = payChannelService.queryByCode(payChannelReq.getCode());
            if (payChannelDb == null) {
                return CommonResult.error(PayResultCode.PAY_CHANNEL_NOT_EXITS);
            }
            // 去掉名称校验
            // PayChannelDO payChannelDO = payChannelService.queryByName(payChannelReq.getName());
            // if (payChannelDO != null && !payChannelDO.getCode().equals(payChannelReq.getCode())) {
            //     return CommonResult.error(PayResultCode.PAY_CHANNEL_EXITS);
            // }
            if (StringUtils.hasText(payChannelReq.getChannelConfig())) {
                try {
                    JsonUtils.parseArray(payChannelReq.getChannelConfig(), Object.class);
                }
                catch (Exception e) {
                    return CommonResult.error(CommonResultCode.PARAMETER_ERROR);
                }
            }
            if (StringUtils.hasText(payChannelReq.getMerchantConfig())) {
                try {
                    JsonUtils.parseArray(payChannelReq.getMerchantConfig(), Object.class);
                }
                catch (Exception e) {
                    return CommonResult.error(CommonResultCode.PARAMETER_ERROR);
                }
            }
            if (StringUtils.hasText(payChannelReq.getSpecialMerchantConfig())) {
                try {
                    JsonUtils.parseArray(payChannelReq.getSpecialMerchantConfig(), Object.class);
                }
                catch (Exception e) {
                    return CommonResult.error(CommonResultCode.PARAMETER_ERROR);
                }
            }
            PayChannelDO payChannelDO = BeanUtil.copy(payChannelReq, PayChannelDO.class);
            if (!CollectionUtils.isEmpty(payChannelReq.getPayWapCodeList())) {
                payChannelDO.setPayCodes(JsonUtils.toJsonString(payChannelReq.getPayWapCodeList()));
            }
            PayChannelDO updatePayChannelDO = BeanUtil.copy(payChannelReq, PayChannelDO.class);
            updatePayChannelDO.setId(payChannelDb.getId());
            if (!CollectionUtils.isEmpty(payChannelReq.getPayWapCodeList())) {
                updatePayChannelDO.setPayCodes(JsonUtils.toJsonString(payChannelReq.getPayWapCodeList()));
            }
            payChannelService.update(updatePayChannelDO);
            // 变更日志
            businessChangeLog(payChannelDb, updatePayChannelDO);
            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("updatePayChannel fail payChannelReq:{},message:{}", JsonUtils.toJsonString(payChannelReq), e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<Void> delPayChannel(String code) {
        log.info("delPayChannel code:{}", code);
        try {
            if (!StringUtils.hasText(code)) {
                return CommonResult.error(CommonResultCode.PARAMETER_MISSING);
            }
            PayChannelDO payChannelDb = payChannelService.queryByCode(code);
            if (payChannelDb == null) {
                return CommonResult.error(PayResultCode.PAY_CHANNEL_NOT_EXITS);
            }
            payChannelService.del(code);
            // 变更日志
            PayChannelDO channelDO = BeanUtil.copy(payChannelDb, PayChannelDO.class);
            channelDO.setDeleteFlag(Boolean.TRUE);
            businessChangeLog(payChannelDb, channelDO);
            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("delPayChannel fail code:{},message:{}", code, e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    @Override
    public CommonResult<Void> updatePayChannelStatus(UpdateStatusReq updateStatusReq) {
        log.info("updatePayChannelStatus updateStatusReq:{}", JsonUtils.toJsonString(updateStatusReq));
        try {
            PayChannelDO payChannelDb = payChannelService.queryByCode(updateStatusReq.getCode());
            if (payChannelDb == null) {
                return CommonResult.error(PayResultCode.PAY_CHANNEL_NOT_EXITS);
            }
            payChannelService.updatePayWayStatus(payChannelDb.getCode(), updateStatusReq.getStatus());
            // 变更日志
            PayChannelDO channelDO = BeanUtil.copy(payChannelDb, PayChannelDO.class);
            channelDO.setStatus(updateStatusReq.getStatus());
            businessChangeLog(payChannelDb, channelDO);
            return CommonResult.success();
        }
        catch (Exception e) {
            log.error("updatePayChannelStatus fail updateStatusReq:{},message:{}", JsonUtils.toJsonString(updateStatusReq), e.getMessage(), e);
            return CommonResult.error(CommonResultCode.SERVICE_ERROR);
        }
    }

    /**
     * log object
     * 
     * @param beforePayChannel
     * @param afterPayChannel
     * @return
     */
    void businessChangeLog(PayChannelDO beforePayChannel, PayChannelDO afterPayChannel) {
        businessChangeLogService.addBusinessChangeLog(beforePayChannel.getCode(), PayEnums.CHANGE_LOG_TYPE.CHANNEL.getCode(), CommonEnum.CHANGE_LOG_MODEL_TYPE.PAY,
                beforePayChannel, afterPayChannel);
    }
}
